package com.zhoug.common3.utils;

import android.app.Application;
import android.content.Context;

import java.io.File;
import java.util.Locale;

/**
 * app文件管理器,最好继承它
 *
 * @Author 35574
 * @Date 2021/11/22
 * @Description
 */
public class FileManager {
    private static final String TAG = ">>>FileManager";
    /**
     * ApplicationContext
     */
    private static Context mContext;
    /**
     * 文件默认是存储在外部存储空间还是内部存储空间,都是私有的别的应用不能访问
     * 优先级大于{@link #isPublic}
     */
    private boolean defExternal = true;

    /**
     * 文件存储在外部,别的应用可以访问
     * 优先级小于{@link #defExternal}
     * 别的应用可以访问需要设置:
     * {@link #defExternal}:true,
     * {@link #isPublic}:true
     */
    private boolean isPublic = true;

    /**
     * 适用于{@link #getExternalPackageDir}方法
     * 指定更具包名创建外部别的应用可访问的目录的父级目录
     * 例:包名是com.heking.mclzfirm 创建的目录是 heking/com.heking.mclzfirm
     */
    private String externalPackageParentDir = "heking";

    /**
     * 静态实例
     */
    private static FileManager mInstance;
    /**
     * 图片保存、缓存地址
     */
    public static String IMG_PATH_SAVE = "image/save/";
    /**
     * 裁剪后图片保存地址
     */
    public static String IMG_PATH_CUT = "image/cut/";
    /**
     * 拍照后图片保存地址
     */
    public static String IMG_PATH_CAPTURE = "image/capture/";
    /**
     * 分享图片的临时保存地址
     */
    public static String IMG_PATH_SHARE = "image/share/";
    /**
     * 视频保存,缓存地址
     */
    public static String VIDEO_PATH_SAVE = "video/";
    /**
     * 音频保存,缓存地址
     */
    public static String AUDIO_PATH_SAVE = "audio/";
    /**
     * 文档保存,缓存地址
     */
    public static String DOC_PATH_SAVE = "doc/";
    /**
     * 更新包保存路径
     */
    public static String APK_PATH_INSTALL = "apk/";


    private FileManager() {
    }

    /**
     * 需要在{@link Application#onCreate()}中初始化
     *
     * @param appContext ApplicationContext
     */
    public static void init(Context appContext) {
        mContext = appContext;
    }

    public static FileManager getInstance() {
        if (mInstance == null) {
            synchronized (FileManager.class) {
                if (mInstance == null) {
                    mInstance = new FileManager();
                }
            }
        }
        return mInstance;
    }

    public void setDefExternal(boolean defExternal) {
        this.defExternal = defExternal;
    }

    public void setPublic(boolean isPublic) {
        this.isPublic = isPublic;
    }

    protected static Context getContext() {
        return mContext;
    }


    /**
     * 获取根目录:data/data/package/
     * 文件默认私有的，即别的应用不能访问，本应用卸载则文件删除
     *
     * @return
     */
    public String getAppDataRootDir() {
        return FileUtils.getAppDataRootDir(getContext());
    }


    /**
     * 获取根目录下的子目录:data/data/package/dirName
     *
     * @return
     */
    public String getAppDataRootDir(String dirName) {
        return FileUtils.getAppDataDir(getContext(), dirName);
    }

    /**
     * 获取App外部储存根目录 android/data/package
     * 只能本应用访问，应用删除文件删除
     *
     * @return
     */
    public String getAppExternalRootDir() {
        return FileUtils.getAppExternalRootDir(getContext());
    }

    /**
     * 获取App外部储存根目录的子目录 android/data/package/dirName
     *
     * @return
     */
    public String getAppExternalRootDir(String dirName) {
        return FileUtils.getAppExternalRootDir(getContext(), dirName);
    }

    /**
     * 外部存储根目录,别的应用可以访问
     *
     * @return
     */
    public String getExternalRootDir() {
        File externalRoot = FileUtils.getExternalRoot();
        return null != externalRoot ? externalRoot.getAbsolutePath() : null;
    }

    /**
     * 外部存目录,别的应用可以访问
     *
     * @return
     */
    public String getExternalRootDir(String dirName) {
        File externalRoot = FileUtils.getExternalRoot();
        if (externalRoot != null) {
            File file = new File(externalRoot, dirName);
            if (!file.exists()) {
                boolean mkdirs = file.mkdirs();
                LogUtils.d(TAG, StringUtils.format("目录创建%s:%s", (mkdirs ? "成功" : "失败"), file.getAbsolutePath()));
            }
            return file.getAbsolutePath();
        }
        return null;
    }

    /**
     * 更具包名创建外部目录,别的应用可以访问
     *
     * @return
     */
    public String getExternalPackageDir() {
        String dir;
        if (!StringUtils.isNullOrEmpty(externalPackageParentDir)) {
            dir = externalPackageParentDir + File.separator + getContext().getPackageName();
        } else {
            dir = getContext().getPackageName();
        }
        return getExternalRootDir(dir);
    }

    /**
     * 更具包名创建外部目录,别的应用可以访问
     *
     * @return
     */
    public String getExternalPackageDir(String dir) {
        String externalPackageDir = getExternalPackageDir();
        if (null != externalPackageDir) {
            File file = new File(externalPackageDir, dir);
            File dirIfNotExist = createDirIfNotExist(file);
            return dirIfNotExist != null ? dirIfNotExist.getAbsolutePath() : null;
        }
        return null;
    }


    /**
     * 图片保存、缓存地址
     *
     * @return
     */
    public File getImageSaveDir() {
        return getImageSaveDir(defExternal,isPublic);
    }

    /**
     * 图片保存、缓存地址
     *
     * @return
     */
    public File getImageSaveDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(IMG_PATH_SAVE));
            }
            return createDirIfNotExist(getAppExternalRootDir(IMG_PATH_SAVE));
        } else {
            return createDirIfNotExist(getAppDataRootDir(IMG_PATH_SAVE));
        }
    }


    /**
     * 裁剪后图片保存地址
     *
     * @return
     */
    public File getImageCutDir() {
        return getImageCutDir(defExternal,isPublic);
    }

    /**
     * 裁剪后图片保存地址
     *
     * @return
     */
    public File getImageCutDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(IMG_PATH_CUT));
            }
            return createDirIfNotExist(getAppExternalRootDir(IMG_PATH_CUT));
        }
        return createDirIfNotExist(getAppDataRootDir(IMG_PATH_CUT));
    }


    /**
     * 拍照后图片保存地址
     *
     * @return
     */
    public File getImageCaptureDir() {
        return getImageCaptureDir(defExternal,isPublic);
    }

    /**
     * 拍照后图片保存地址
     *
     * @return
     */
    public File getImageCaptureDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(IMG_PATH_CAPTURE));
            }
            return createDirIfNotExist(getAppExternalRootDir(IMG_PATH_CAPTURE));
        }
        return createDirIfNotExist(getAppDataRootDir(IMG_PATH_CAPTURE));
    }

    /**
     * 分享图片的临时保存地址
     *
     * @return
     */
    public File getImageShareDir() {
        return getImageShareDir(defExternal,isPublic);
    }

    /**
     * 分享图片的临时保存地址
     *
     * @return
     */
    public File getImageShareDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(IMG_PATH_SHARE));
            }
            return createDirIfNotExist(getAppExternalRootDir(IMG_PATH_SHARE));
        }
        return createDirIfNotExist(getAppDataRootDir(IMG_PATH_SHARE));
    }

    /**
     * 视频保存,缓存地址
     *
     * @return
     */
    public File getVideoSaveDir() {
        return getVideoSaveDir(defExternal,isPublic);
    }

    /**
     * 视频保存,缓存地址
     *
     * @return
     */
    public File getVideoSaveDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(VIDEO_PATH_SAVE));
            }
            return createDirIfNotExist(getAppExternalRootDir(VIDEO_PATH_SAVE));
        }
        return createDirIfNotExist(getAppDataRootDir(VIDEO_PATH_SAVE));
    }


    /**
     * 音频保存,缓存地址
     *
     * @return
     */
    public File getAudioSaveDir() {
        return getAudioSaveDir(defExternal,isPublic);
    }


    /**
     * 音频保存,缓存地址
     *
     * @return
     */
    public File getAudioSaveDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(AUDIO_PATH_SAVE));
            }
            return createDirIfNotExist(getAppExternalRootDir(AUDIO_PATH_SAVE));

        }
        return createDirIfNotExist(getAppDataRootDir(AUDIO_PATH_SAVE));
    }

    /**
     * 文档保存,缓存地址
     *
     * @return
     */
    public File getDocSaveDir() {
        return getDocSaveDir(defExternal,isPublic);
    }

    /**
     * 文档保存,缓存地址
     *
     * @return
     */
    public File getDocSaveDir(boolean external,boolean isPublic) {
        if (external) {
            if(isPublic){
                return createDirIfNotExist(getExternalPackageDir(DOC_PATH_SAVE));
            }
            return createDirIfNotExist(getAppExternalRootDir(DOC_PATH_SAVE));
        }
        return createDirIfNotExist(getAppDataRootDir(DOC_PATH_SAVE));
    }


    /**
     * 更新包保存路径
     *
     * @return
     */
    public File getApkInstallDir() {
        return createDirIfNotExist(getAppExternalRootDir(APK_PATH_INSTALL));
    }

    /**
     * 创建文件夹,文件夹不存在则创建,存在则直接返回
     *
     * @param path
     */
    public File createDirIfNotExist(String path) {
        return createDirIfNotExist(new File(path));
    }

    /**
     * 创建文件夹,文件夹不存在则创建,存在则直接返回
     *
     * @param file
     */
    public File createDirIfNotExist(File file) {
        if (file == null) {
            return null;
        }
        if (!FileUtils.createDirectory(file)) {
            LogUtils.e(TAG, String.format(Locale.CANADA, "创建文件夹失败:%s", file.getAbsolutePath()));
        }
        return file;
    }


    /**
     * 创建文件,文件不存在则创建,存在则直接返回
     *
     * @param path
     */
    public File createFileIfNotExist(String path) {
        return createFileIfNotExist(new File(path));
    }

    /**
     * 创建文件,文件不存在则创建,存在则直接返回
     *
     * @param file
     * @return 创建失败返回null
     */
    public File createFileIfNotExist(File file) {
        if (file == null) {
            return null;
        }
        if (!FileUtils.createFile(file)) {
            LogUtils.e(TAG, String.format(Locale.CANADA, "创建文件失败:%s", file.getAbsolutePath()));
        }
        return file;
    }


    /**
     * 图片保存、缓存地址
     *
     * @param name       图片名称 eg:xxx/xxx.jpg
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getImageSavePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getImageSaveDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 图片保存、缓存地址
     *
     * @param name 图片名称 eg:xxx/xxx.jpg
     * @return
     */
    public File getImageSavePath(String name) {
        return getImageSavePath(name, false);
    }


    /**
     * 裁剪后图片保存地址
     *
     * @param name       图片名称 eg:xxx/xxx.jpg
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getImageCutPath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getImageCutDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 裁剪后图片保存地址
     *
     * @param name 图片名称 eg:xxx/xxx.jpg
     * @return
     */
    public File getImageCutPath(String name) {
        return getImageCutPath(name, false);
    }


    /**
     * 拍照后图片保存地址
     *
     * @param name       图片名称 eg:xxx/xxx.jpg
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getImageCapturePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getImageCaptureDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 拍照后图片保存地址
     *
     * @param name 图片名称 eg:xxx/xxx.jpg
     * @return
     */
    public File getImageCapturePath(String name) {
        return getImageCapturePath(name, false);
    }


    /**
     * 分享图片的临时保存地址
     *
     * @param name       图片名称 eg:xxx/xxx.jpg
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getImageSharePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getImageShareDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 分享图片的临时保存地址
     *
     * @param name 图片名称 eg:xxx/xxx.jpg
     * @return
     */
    public File getImageSharePath(String name) {
        return getImageSharePath(name, false);
    }


    /**
     * 视频保存,缓存地址
     *
     * @param name       视频名称 eg:xxx/xxx.mp4
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getVideoSavePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getVideoSaveDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 视频保存,缓存地址
     *
     * @param name 视频名称 eg:xxx/xxx.mp4
     * @return
     */
    public File getVideoSavePath(String name) {
        return getVideoSavePath(name, false);
    }


    /**
     * 音频保存,缓存地址
     *
     * @param name       音频名称 eg:xxx/xxx.mp3
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getAudioSavePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getAudioSaveDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 音频保存,缓存地址
     *
     * @param name 音频名称 eg:xxx/xxx.mp3
     * @return
     */
    public File getAudioSavePath(String name) {
        return getAudioSavePath(name, false);
    }


    /**
     * 文档保存,缓存地址
     *
     * @param name       文档名称 eg:xxx/xxx.docx
     * @param autoCreate 是否自动创建
     * @return 如果自动创建, 创建失败返回null
     */
    public File getDocSavePath(String name, boolean autoCreate) {
        if (name == null) {
            return null;
        }
        File file = new File(getDocSaveDir(), name);
        if (autoCreate) {
            return createFileIfNotExist(file);
        }
        return file;
    }

    /**
     * 文档保存,缓存地址
     *
     * @param name 文档名称 eg:xxx/xxx.docx
     * @return
     */
    public File getDocSavePath(String name) {
        return getDocSavePath(name, false);
    }


    /**
     * 更新包保存路径
     *
     * @param name 名称 eg:xxx/xxx.apk
     * @return
     */
    public File getApkInstallPath(String name) {
        if (name == null) {
            return null;
        }
        return new File(getApkInstallDir(), name);
    }


}
